<!--
 * @Description:图例
 * @Author: zhjf
 * @Date: 2020-12-23 13:36:48
 * @LastEditors: zhjf
 * @LastEditTime: 2021-07-21 15:56:07
 * @FilePath: \DLYB.Vue\src\components\Common\SimpleLegend.vue
-->
<template>
	<view class="simple-legend">
		<view v-if="options.layout === 'h'" class="title-box">
			<view>
				<!-- 数据标题 -->
				<text class="title-legned-set">
					{{ options.legendData && options.legendData.desc ? options.legendData.desc : '' }}
				</text>
				<input v-if="openFilter" type="number" class="index_filter" @change="(e) => fiterCG(e.target.value)" />
			</view>

			<view class="title-boxTile" v-if="options.boxTile">
				<view class="boxTile" v-for="i in options.boxTile" :key="i.min" :style="`width:${i.bit}`">
					{{ i.name }}
				</view>
			</view>
		</view>

		<!-- 图例标题 -->
		<view
			class="title-legned-set"
			v-if="options.layout !== 'h'"
			:class="[{ 'legend-title-h': options.layout === 'h' }, options.titleClass]"
		>
			<text>
				<!-- {{
        options.legendData && options.legendData.title
          ? options.legendData.title
          : ""
      }} -->
			</text>
		</view>

		<!-- 图例色标 -->
		<ul :style="ulStyle" class="ul_box">
			<li
				v-for="(item, index) in options.legendData.items"
				:key="index"
				:style="getLiStyle(item, index)"
				@click.stop="onLegendItemClick(item, index)"
			>
				<text :style="getLabelStyle(item, index)" :class="[options.labelClass]">{{ item.desc }}</text>
			</li>
		</ul>

		<!-- 图例单位 -->
		<view v-if="options.layout !== 'h'" :class="[{ 'legend-unit-h': options.layout === 'h' }, options.unitClass]">
			<text>{{ options.legendData.unit }}</text>
		</view>

		<view v-if="options.layout === 'h'" class="legend-unit-v">
			<text v-if="options.legendData.unit">({{ options.legendData.unit }})</text>
		</view>
	</view>
</template>

<script>
	export default {
		name: 'SimpleLegend',
		props: {
			legendOptions: {
				type: Object,
				default() {
					return {
						legendData: {}
					}
				}
			},
			legendData: {
				type: Object,
				default: () => {}
			},
			// 自定义过滤数值
			openFilter: {
				type: Boolean,
				default: false
			},
			// 是否不允许点击
			isNoCilck: {
				type: Boolean,
				default: false
			}
		},
		data() {
			return {
				filterIndex: -1,
				options: {
					id: 'legendId',
					layout: 'v', // 色标排列：v：纵向排列（label采用desc字段），h：横向排列（label采用desc字段）
					totalWidth: '450', // 色标项总宽度
					itemWidth: '26', // 色标宽度
					itemHeight: '18', // 色标高度
					filterable: true, // 是否启用过滤
					filterDir: 'desc', // 过滤方向，asc：li索引值从小到大过滤，desc：li索引值从大到小过滤 （li色标索引值固定从左->右、上->下递增）
					filteredColor: '#8E8D8D', // 过滤后颜色

					labelPosition: 'default', // label方向：default：默认左或下、right：右边、top：上面
					labelAlign: 'middle', // label对齐：edge：边缘（label采用desc字段），middle：中间（label采用desc字段）
					labelSide: 'outside', // outside：色标外（label采用desc字段），inside：色标内（label采用desc字段）

					boxClass: '', // 图例盒子样式
					labelClass: '', // label样式
					titleClass: '', // 图例标题样式
					unitClass: '', // 单位样式

					legendData: null, // 图例数据
					curSelectedObj: null, // 当前选中过滤项对象信息
					onItemClick: null, // 实际环境图例色标项点击事件

					textGapShow: null, // number
					boxTile: null
				}
			}
		},
		components: {},
		computed: {
			// 图例项宽度
			legendItemWidth() {
				if (this.options.totalWidth) {
					return this.options.totalWidth / this.options.legendData.items.length
				}
				return this.options.itemWidth
			},
			ulStyle() {
				return this.options.layout === 'v' ? 'margin:0;padding:0;' : 'margin:0;padding:0;display:inline-block;'
			}
		},
		watch: {
			legendOptions(val) {
				this.options = { ...this.options, ...val }
				console.log(`val:`, val)
				this.filterIndex = -1
			},
			legendData() {
				this.options = { ...this.options, ...this.legendOptions }
			}
		},
		created() {
			this.options = { ...this.options, ...this.legendOptions }
		},
		mounted() {},
		methods: {
			onLegendItemClick(item, index) {
				if (this.isNoCilck) {
					return
				}
				this.filterIndex = index
				if (this.options.onItemClick) {
					item.index = index
					this.options.onItemClick(item)
				}
			},

			setIndex(index) {
				this.filterIndex = index
			},

			// 自定义属性
			fiterCG(val) {
				this.options.onItemClick({
					color: '',
					min: parseFloat(val) || 999,
					max: parseFloat(val) || 999,
					desc: '自定义'
				})
			},
			/**
			 * @description: 图例项样式
			 * @param {*} item
			 * @param {*} i
			 * @return {*}
			 * @author: zhjf
			 */
			getLiStyle(item, i) {
				const floatStyle = this.options.layout === 'h' ? 'float: left;' : ''
				const borderStyle = this.options.layout === 'h' ? 'border-left: none;' : 'border-top: none;'
				let color = String(item.color).indexOf('#') !== -1 ? item.color : this.toHexColor(item.color)
				if (
					(this.filterIndex >= 0 && this.options.filterDir === 'asc' && i < this.filterIndex) ||
					(this.filterIndex >= 0 && this.options.filterDir === 'desc' && i > this.filterIndex)
				) {
					color = this.options.filteredColor
				}
				//   width:${this.legendItemWidth}rpx;
				let liStyle = `list-style: none;position: relative;flex:1;height:${this.options.itemHeight}rpx;background-color:${color};box-sizing:initial;`
				liStyle += floatStyle
				if (i !== 0) liStyle += borderStyle
				return liStyle
			},

			/**
			 * @description: label样式
			 * @param {*} item
			 * @param {*} i
			 * @return {*}
			 * @author: zhjf
			 */
			getLabelStyle(item, i) {
				let spanStyle = ''
				if (this.options.layout === 'v') {
					// 垂直
					const left =
						this.options.labelSide === 'inside'
							? 'right: 0;left:0;text-align: center;'
							: (this.options.labelPosition === 'default' || this.options.labelPosition === 'right'
									? 'left:'
									: 'right:') +
							  (Number(this.legendItemWidth) + 2) +
							  'rpx;'
					const top1 =
						this.options.labelAlign === 'middle' || this.options.labelSide === 'inside'
							? 0
							: Number(this.options.itemHeight) / 2 + 'rpx;'
					spanStyle = `position: absolute;${left} top: ${top1};line-height: initial;width: max-content; width: -webkit-max-content;width: -moz-max-content;`
				} else {
					// 水平
					const top =
						this.options.labelSide === 'inside'
							? 'top:initial'
							: (this.options.labelPosition === 'default' || this.options.labelPosition === 'top'
									? 'bottom:'
									: 'top:') +
							  (Number(this.options.itemHeight) + 6) +
							  'rpx'
					const right =
						this.options.labelAlign === 'middle' || this.options.labelSide == 'inside'
							? 'right: 0;left:0;text-align: center;'
							: 'left: -7px;'
					spanStyle = `position: absolute;${top};line-height: initial;width: max-content; width: -webkit-max-content;width: -moz-max-content;${right}`

					// 单个图例宽度太窄时，标注间隔显示
					const textGapShow = this.options.textGapShow
					if (this.options.textGapShow && i % textGapShow !== 0) {
						// console.log(`this.options.textGapShow:`, i / this.options.textGapShow)
						spanStyle += ';display:none;'
					} else if (!this.options.textGapShow && this.legendItemWidth < 25 && i % 2 !== 0) {
						spanStyle += ';display:none;'
					}
				}
				spanStyle += this.options.labelSide === 'inside' ? 'color:' + this.oppositeColor(item.color) + ';' : ''
				return spanStyle
			},

			toHexColor(num) {
				var s = num.toString(16)
				while (s.length < 6) {
					s = '0' + s
				}
				return '#' + s
			},

			oppositeColor(a) {
				a = a.replace('#', '')
				var c16
				var c10
				var max16 = 15
				var b = []
				for (var i = 0; i < a.length; i++) {
					c16 = parseInt(a.charAt(i), 16) //  to 16进制
					c10 = parseInt(max16 - c16, 10) // 10进制计算
					b.push(c10.toString(16)) // to 16进制
				}
				return '#' + b.join('')
			}
		}
	}
</script>

<style scoped lang="scss">
	.simple-legend {
		padding: 5px 10px 0 10px;
		color: #000;
		font-size: 20rpx;
		display: flex;
		align-items: center;
		.ul_box {
			flex: 1;
			display: flex !important;
			margin: 0 5rpx !important;
			// width: 100%
		}
		.legend-title {
			text-align: center;
		}
		.title-box {
			display: flex;
			justify-content: space-between;
			position: relative;

			max-width: 120rpx;
		}
		.legend-title-h {
			display: inline-block;
			vertical-align: top;
			padding: 0 2px;
		}
		.legend-unit-h {
			display: inline-block;
			vertical-align: top;
			padding: 0 2px;
		}
		.index_filter {
			width: 65px;
		}
		.title-boxTile {
			width: 100%;
			position: absolute;
			top: 0px;
			left: 0;
			font-size: 12px;
			display: flex;
			.boxTile {
				text-align: center;
			}
		}
	}
</style>
